#ifndef MUSINKSUBMITTER_H
#define MUSINKSUBMITTER_H


/**
\mainpage MusinkSubmitter

\section intro_sec Introduction

Win32 Library for writing player plugins to submit song data to the MuSink DataManager

\section install_sec Installation

This library has only one public interface, MusinkSubmitter.  It is recommended that
you use it by including all relevant files in your project.

Files Needed:
\li MusinkSubmitter.h
\li MusinkSubmitter.cpp
\li MusinkSong.h
\li NetworkHandler.h
\li NetworkHandler.cpp

\section dep_sec Dependencies

Win32 and Winsock2

\section notes_sec Notes
Winsock2 must be added as an additional dependency for the linker. 

MusinkSubmitter.getSong() should be used to create every MusinkSong Object, to ensure that the hash is correct.

MSVC2003: Project -> MusinkSubmitter Properties -> Linker -> Input -> Add'l Dependencies -> wsock32.lib

*/

#include <string>
#include <deque>
#include <vector>
#include "NetworkHandler.h"
#include "MusinkSong.h"
using namespace std;


class MusinkSong;

/**
 * Class for working with the Musink Database Manager
 */

class MusinkSubmitter
{
public:
	class MusinkException: public std::logic_error {
		public:
			MusinkException(const std::string& sMsg) : logic_error(sMsg) { }
		};

	/**
	* Constructor 
	*/

	MusinkSubmitter();

	/**
	* Constructor
	*
	* @param[in] id Plugin ID existing from a previous session
	*/
	MusinkSubmitter::MusinkSubmitter(string id);

	/**
	 * Destructor
	 */

	~MusinkSubmitter();
	
	/**
	* Get pluginID 
	*
	* returns pluginID as assigned by Database Manager (first time)
	*/

	string getID();
	
	/*
	* Get a list of songChanges from the server
	* This should be run at the start up of an 'old' player
	* 
	* @param[out] library Contains a list of all songs which have changed since last sync with DatabaseManager
	*/

	void getChanges(vector<MusinkSong> &library);

	/**
	* Gets all data about a song from the DatabaseManager (Should be used to get every song to be updated)
	*
	* @param[in] filename Contains the file name of the song of interest
	*
	* returns MusinkSong object containing the data the Manager has on the file selected
	*/
	MusinkSong getSong(const string & filename);
	
	/**
	* Gets all data about a song from the DatabaseManager based on Hash
	*
	* @param[in] hash
	*
	* returns MusinkSong object containing the data the Manager has on the hash provided
	*/ 

	MusinkSong getSongByHash(const string & hash);

	/**
	* Sends all local data about a song to the DatabaseManager to be updated (including Meta Tags as seen by the Player)
	*
	* @param[in] song Song to be updated
	*/

	void updateSong(const MusinkSong & song);

	/**
	* Sync up local library (player or portable) with the DatabaseManager
	* This should be run at the start of a 'new' player or when a portable is synced
	*
	* @param[in] library Contains all songs that need to be updated
	* @param[out] conflicts Contains a list of songs that have conflicting data (i.e. Different Ratings) that need to be resolved. Resolve via updateSong
	*/

	void syncDatabases(vector<MusinkSong> &library, vector<MusinkSong> &conflicts);
	
	/**
	* Gets song data for multiple files from the Database Manager.
	* This should be run to get a consistant library (i.e. has correct hashes) for use with MusinkSubmitter::syncDatabases
	* After running this function, update all properties of a MusinkSong except fileName, and hash
	*
	* @param[in] files Contains full paths to all files that song data is needed for
	*/
	vector<MusinkSong> MusinkSubmitter::songCollection(const vector<string> & files);

private:
	//Private Functions
	string escape(const string &str);
	string unescape(const string &str);
	vector<string> splitVariables(string &inString);
	

	//Private Variables
	vector<MusinkSong> myLibrary;
	string myPluginID;
	NetworkHandler mySock;
	unsigned int myPort;



};

#endif //MUSINKSUBMITTER_H